package br.ufrrj.im.redes.view;

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;
import javax.swing.border.LineBorder;
import java.awt.Color;

import javax.swing.DefaultListModel;
import javax.swing.JLabel;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.JOptionPane;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.JButton;
import javax.swing.JList;
import javax.swing.JScrollPane;

import br.ufrrj.im.redes.server.Server;

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.IOException;

public class ServerWIndow {
	
	private JPanel panel;
	private JList<String> list;
	private DefaultListModel<String> listModel;
	private JLabel lblMnimo;
	private JFrame frmCriarServidor;
	private JPanel panel_1;
	private JButton btnPararServidor;
	private JButton btnIniciarServidor;
	private JButton btnIniciarJogo;	
	private boolean serverInitialized = false;
	private JSpinner spinner;
	
	private int rangePrime;
	
	private Server server;
	private Thread updatesStatusThread;
		
	
	private void exit(){		
		frmCriarServidor.setVisible(false);
		System.exit(1);
	}
	
	private boolean requestStopServer() {
		if (serverInitialized)
		{
			int msgBox = JOptionPane.showConfirmDialog(frmCriarServidor,
					"Você realmente deseja interromper a execução do servidor? \nTodos as conexões estabelecidas serão encerradas.", "Parar servidor",
					JOptionPane.YES_NO_OPTION);

			// Sim ou não
			if (msgBox == JOptionPane.YES_OPTION){
				return stopServer();
			}
			else
				return false;
		}
		
		return true;
	}
	
	@SuppressWarnings("deprecation")
	private boolean stopServer(){
		
		serverInitialized = false;
		try {
			server.stopServer();
			this.serverInitialized = false;
			updatesStatusThread.stop();
			return true;
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			JOptionPane.showMessageDialog(frmCriarServidor, e.toString(), "Erro ao encerrar conexão do servidor", JOptionPane.ERROR_MESSAGE);
		}
		
		return false;
	}
	
	private void startServer(){
		
		try {
			updatesStatusThread = new Thread();
			
			server = new Server(rangePrime);
			
			//servidor aguarda conexões
			server.reciveConnection();
			
			serverInitialized = true;
			JOptionPane.showMessageDialog(frmCriarServidor, "Servidor inicializado com sucesso!", "Servidor inicializado", JOptionPane.INFORMATION_MESSAGE);

			
			//atualiza lista de usuários conectados
			updatesStatusThread = new Thread(new Runnable() {
				
				@Override
				public void run() {
					// TODO Auto-generated method stub
					
					//Enquanto o servidor estiver conectado
					while(server.isConnectedServer()){

						//Se houve mudanças na lista de usuários disponpíveis, então atualiza o JList
						if(server.isChangedAvaibleUsers()){
							
							for (String userName : server.getListOfAvaibleUsers().keySet()) {
							
								listModel.clear();
								listModel.addElement(userName + " :: se encontra conectado ao servidor.");
								list.setModel(listModel);
								server.setChangedAvaibleUsers(false);
							}							
						}
					}
				}
			});
			
			updatesStatusThread.start();
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			JOptionPane.showMessageDialog(frmCriarServidor, e.toString(), "Falha no processo de autenticação", JOptionPane.ERROR_MESSAGE);
		}		
	}
	
	private void startGame(){
		
		server.startGame();
		JOptionPane.showMessageDialog(frmCriarServidor, "Jogo inicializado com sucesso!", "Jogo inicializado", JOptionPane.INFORMATION_MESSAGE);
	}
	
	


	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					ServerWIndow window = new ServerWIndow();
					window.frmCriarServidor.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}
	
	public void showWindow(){
		this.frmCriarServidor.setVisible(true);
	}

	/**
	 * Create the application.
	 */
	public ServerWIndow() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frmCriarServidor = new JFrame();
		frmCriarServidor.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {	
				
				if(requestStopServer())
					exit();
				
			}
		});
		frmCriarServidor.setTitle("Gerenciar Servidor");
		frmCriarServidor.setBounds(100, 100, 469, 449);
		frmCriarServidor.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		
		panel = new JPanel();
		panel.setBorder(new TitledBorder(new LineBorder(new Color(184, 207, 229)), "Alcance n\u00FAmeros primos (d\u00EDgitos decimais)", TitledBorder.LEADING, TitledBorder.TOP, null, null));
				
		btnIniciarServidor = new JButton("Iniciar Servidor");
		btnIniciarServidor.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
				rangePrime = ((Integer)spinner.getValue()).intValue();
				startServer();
				
				if(serverInitialized){
					btnPararServidor.setEnabled(true);
					btnIniciarJogo.setEnabled(true);
					btnIniciarServidor.setEnabled(false);
				}
					
				
			}
		});
		btnIniciarServidor.setMnemonic('S');
		
		panel_1 = new JPanel();
		panel_1.setBorder(new TitledBorder(null, "Jogadores Conectados", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		
		btnIniciarJogo = new JButton("Iniciar Jogo");
		btnIniciarJogo.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
				startGame();
				
				if(server.isGameStarted()){
					btnIniciarJogo.setEnabled(false);
				}
					
			}
		});
		btnIniciarJogo.setEnabled(false);
		btnIniciarJogo.setMnemonic('J');
		
		btnPararServidor = new JButton("Parar Servidor");
		btnPararServidor.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				requestStopServer();
				
				if(!serverInitialized){
					btnPararServidor.setEnabled(false);
					btnIniciarJogo.setEnabled(false);
					btnIniciarServidor.setEnabled(true);
				}

				
			}
		});
		btnPararServidor.setEnabled(false);
		btnPararServidor.setMnemonic('P');
		GroupLayout groupLayout = new GroupLayout(frmCriarServidor.getContentPane());
		groupLayout.setHorizontalGroup(
			groupLayout.createParallelGroup(Alignment.LEADING)
				.addGroup(groupLayout.createSequentialGroup()
					.addGap(22)
					.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
						.addGroup(groupLayout.createSequentialGroup()
							.addComponent(btnIniciarServidor)
							.addPreferredGap(ComponentPlacement.UNRELATED)
							.addComponent(btnPararServidor)
							.addPreferredGap(ComponentPlacement.UNRELATED)
							.addComponent(btnIniciarJogo)
							.addGap(41))
						.addGroup(Alignment.TRAILING, groupLayout.createSequentialGroup()
							.addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
								.addComponent(panel_1, GroupLayout.DEFAULT_SIZE, 433, Short.MAX_VALUE)
								.addComponent(panel, GroupLayout.DEFAULT_SIZE, 433, Short.MAX_VALUE))
							.addGap(31))))
		);
		groupLayout.setVerticalGroup(
			groupLayout.createParallelGroup(Alignment.LEADING)
				.addGroup(groupLayout.createSequentialGroup()
					.addContainerGap()
					.addComponent(panel, GroupLayout.PREFERRED_SIZE, 71, GroupLayout.PREFERRED_SIZE)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
						.addComponent(btnIniciarServidor)
						.addComponent(btnPararServidor)
						.addComponent(btnIniciarJogo))
					.addGap(18)
					.addComponent(panel_1, GroupLayout.DEFAULT_SIZE, 287, Short.MAX_VALUE))
		);
		
		JScrollPane scrollPane = new JScrollPane();
		GroupLayout gl_panel_1 = new GroupLayout(panel_1);
		gl_panel_1.setHorizontalGroup(
			gl_panel_1.createParallelGroup(Alignment.LEADING)
				.addComponent(scrollPane, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 423, Short.MAX_VALUE)
		);
		gl_panel_1.setVerticalGroup(
			gl_panel_1.createParallelGroup(Alignment.LEADING)
				.addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 266, Short.MAX_VALUE)
		);
		
		list = new JList<String>();
		listModel = new DefaultListModel<String>();
		list.setModel(listModel);
		
		scrollPane.setViewportView(list);
		panel_1.setLayout(gl_panel_1);
		
		
		lblMnimo = new JLabel("Máximo:");
		
		spinner = new JSpinner();
		spinner.setModel(new SpinnerNumberModel(5, 1, 18, 1));
		GroupLayout gl_panel = new GroupLayout(panel);
		gl_panel.setHorizontalGroup(
			gl_panel.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_panel.createSequentialGroup()
					.addContainerGap()
					.addComponent(lblMnimo)
					.addPreferredGap(ComponentPlacement.UNRELATED)
					.addComponent(spinner, GroupLayout.PREFERRED_SIZE, 68, GroupLayout.PREFERRED_SIZE)
					.addContainerGap(224, Short.MAX_VALUE))
		);
		gl_panel.setVerticalGroup(
			gl_panel.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_panel.createSequentialGroup()
					.addContainerGap()
					.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
						.addComponent(lblMnimo)
						.addComponent(spinner, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
					.addContainerGap(22, Short.MAX_VALUE))
		);
		panel.setLayout(gl_panel);
		frmCriarServidor.getContentPane().setLayout(groupLayout);
	}
}
